/**
 *
 */
package com.ybkj.daijia.server.service.impl;


import com.ybkj.daijia.serverUtils.SettingUtils;
import com.ybkj.daijia.WxSetting;
import com.ybkj.daijia.api.weixin.tenpayv3.Configuration;
import com.ybkj.daijia.api.weixin.tenpayv3.GetWxOrderno;
import com.ybkj.daijia.api.weixin.tenpayv3.RequestHandler;
import com.ybkj.daijia.api.weixin.tenpayv3.TenpayUtil;
import com.ybkj.daijia.common.Principal;
import com.ybkj.daijia.common.Result;
import com.ybkj.daijia.page.Page;
import com.ybkj.daijia.page.Pageable;
import com.ybkj.daijia.page.impl.PageImpl;
import com.ybkj.daijia.page.impl.PageRequest;
import com.ybkj.daijia.server.Config;
import com.ybkj.daijia.server.mapper.CompanyMapper;
import com.ybkj.daijia.server.mapper.FinancialRecordMapper;
import com.ybkj.daijia.server.mapper.WeixinManagerMapper;
import com.ybkj.daijia.server.mapper.WeixinManagerPaymentsMapper;
import com.ybkj.daijia.server.mapper.WeixinManagerTixianRecordMapper;
import com.ybkj.daijia.server.model.WeixinManager;
import com.ybkj.daijia.server.model.WeixinManagerPayments;
import com.ybkj.daijia.server.model.WeixinManagerTixianRecord;
import com.ybkj.daijia.server.service.WeixinManagerTixianRecordService;
import java.io.File;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author Shine
 *
 */
@Service
public class DefaultWeixinManagerTixianRecordService implements WeixinManagerTixianRecordService {

    @Autowired
    private WeixinManagerTixianRecordMapper weixinManagerTixianRecordMapper;

    @Autowired
    private WeixinManagerMapper weixinManagerMapper;

    @Autowired
    private CompanyMapper companyMapper;

    @Autowired
    private FinancialRecordMapper financialRecordMapper;

    @Autowired
    private WeixinManagerPaymentsMapper weixinManagerPaymentsMapper;

    @Autowired
    private SettingUtils settingUtils;


    @Transactional(rollbackFor = Exception.class)
    public WeixinManagerTixianRecord insertRecord(
        WeixinManagerTixianRecord weixinManagerTixianRecord) {

        weixinManagerTixianRecordMapper.insertRecord(weixinManagerTixianRecord);

        return weixinManagerTixianRecord;
    }


    @Transactional(rollbackFor = Exception.class)
    public void update(WeixinManagerTixianRecord weixinManagerTixianRecord) {

        weixinManagerTixianRecordMapper.updateByPrimaryKey(weixinManagerTixianRecord);

    }

    @Transactional(rollbackFor = Exception.class)
    public void cancelTixian(WeixinManager weixinManager,
        WeixinManagerTixianRecord weixinManagerTixianRecord) {

        weixinManagerTixianRecordMapper.deleteByPrimaryKey(weixinManagerTixianRecord.getId());
        weixinManager
            .setVirtual(weixinManager.getVirtual().add(weixinManagerTixianRecord.getMoney()));
        weixinManagerMapper.updateByPrimaryKey(weixinManager);

    }

    @Override
    public WeixinManagerTixianRecord findOne(Long id) {

        return weixinManagerTixianRecordMapper.selectByPrimaryKey(id);
    }

    @Override
    public Page<WeixinManagerTixianRecord> queryAll(Long managerId, Integer page, Integer limit,
        Date start, Date end, String param) {

        Subject currentUser = SecurityUtils.getSubject();
        Principal principal = (Principal) currentUser.getPrincipal();

        Pageable pageable = new PageRequest(page, limit);

        Map<String, Object> params = new HashMap<String, Object>();

        if (!principal.isCompanyType()) {
            params.put("companyId", principal.getCompanyId());
        } else {
            params.put("companyId", null);
        }

        if (null != managerId) {
            params.put("managerId", managerId);
        }

        if (null != start) {
            params.put("start", start);
        }

        if (null != end) {
            params.put("end", end);
        }

        if (StringUtils.isNotBlank(param)) {
            params.put("param", "%" + param + "%");
        }

        params.put("offset", page * limit);
        params.put("size", limit);

        List<WeixinManagerTixianRecord> content = weixinManagerTixianRecordMapper
            .selectByParams(params);
        long total = weixinManagerTixianRecordMapper.countByParams(params);

        return new PageImpl<WeixinManagerTixianRecord>(content, pageable, total);
    }

    @Transactional(rollbackFor = Exception.class)
    public Result<WeixinManagerTixianRecord> tixianAudit(
        WeixinManagerTixianRecord weixinManagerTixianRecord, WeixinManager weixinManager,
        HttpServletResponse response, HttpServletRequest request) {

        Result<WeixinManagerTixianRecord> vo = new Result<WeixinManagerTixianRecord>();

        Subject currentUser = SecurityUtils.getSubject();
        Principal principal = (Principal) currentUser.getPrincipal();

        WeixinManagerTixianRecord db_weixinManagerTixianRecord = weixinManagerTixianRecordMapper
            .selectByPrimaryKey(weixinManagerTixianRecord.getId());

        if (weixinManagerTixianRecord.getStatus().equals(WeixinManagerTixianRecord.STATUS_OK)) {

            //微信转账
            WxSetting wxSetting = settingUtils.getWx();

            //商户相关资料
            String appid = wxSetting.getWxAppId();
            String appsecret = wxSetting.getWxAppSecret();
            String partner = wxSetting.getWxPartnerId();
            String partnerkey = wxSetting.getWxPartnerKey();

            if (null == appid || appid.isEmpty()) {
                vo.setMessage("appid未设置");
                return vo;
            }
            if (null == appsecret || appsecret.isEmpty()) {
                vo.setMessage("appsecret未设置");
                return vo;
            }
            if (null == partner || partner.isEmpty()) {
                vo.setMessage("partner未设置");
                return vo;
            }
            if (null == partnerkey || partnerkey.isEmpty()) {
                vo.setMessage("partnerkey未设置");
                return vo;
            }

            String webapp = Config.getWebapp();
            File certFile = new File(String.format("%s/upload/wx/cert/apiclient_cert.p12", webapp));
            if (!certFile.exists()) {
                vo.setMessage("未上传商户证书");
                return vo;
            }

            // 获取该用户的openid
            String openid = weixinManager.getWxuser();
            if (null == openid) {
                vo.setMessage("客户经理未绑定微信，不能提现");
                return vo;
            }

            //获取openId后调用统一支付接口https://api.mch.weixin.qq.com/pay/unifiedorder
            String currTime = TenpayUtil.getCurrTime();
            //8位日期
            String strTime = currTime.substring(8, currTime.length());
            //四位随机数
            String strRandom = TenpayUtil.buildRandom(6) + "";
            //10位序列号,可以自行调整。
            String strReq = strTime + strRandom;

            String transfersURL = Configuration.transfersURL;

            //商户号
            String mch_id = partner;
            //随机数
            String nonce_str = strReq;
            //商品描述
            String desc = "客户经理提现";
            //商户订单号
            String out_trade_no = strReq;
            //总金额以分为单位，不带小数点
            String total_fee = String.valueOf(
                weixinManagerTixianRecord.getMoney().multiply(new BigDecimal(100)).intValue());
//          total_fee="100";
            //订单生成的机器 IP
            String spbill_create_ip = request.getRemoteAddr();
            ;

            SortedMap<String, String> packageParams = new TreeMap<String, String>();
            packageParams.put("mch_appid", appid);
            packageParams.put("mchid", mch_id);
            packageParams.put("nonce_str", nonce_str);
            packageParams.put("partner_trade_no", out_trade_no);
            packageParams.put("openid", openid);
            packageParams.put("check_name", "NO_CHECK");
            packageParams.put("re_user_name", weixinManager.getName());

            //这里写的金额为1 分到时修改
            packageParams.put("amount", total_fee);
            packageParams.put("desc", desc);
            packageParams.put("spbill_create_ip", spbill_create_ip);

            RequestHandler reqHandler = new RequestHandler(request, response);
            reqHandler.init(appid, appsecret, partnerkey);

            String sign = reqHandler.createSign(packageParams);
            String xml = "<xml>" +
                "<mch_appid>" + appid + "</mch_appid>" +
                "<mchid>" + mch_id + "</mchid>" +
                "<nonce_str>" + nonce_str + "</nonce_str>" +
                "<partner_trade_no>" + out_trade_no + "</partner_trade_no>" +
                "<openid>" + openid + "</openid>" +
                "<check_name>NO_CHECK</check_name>" +
                "<re_user_name>" + weixinManager.getName() + "</re_user_name>" +
                "<amount>" + total_fee + "</amount>" +
                "<desc>" + desc + "</desc>" +
                "<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>" +
                "<sign>" + sign + "</sign>" +
                "</xml>";

            Map<String, String> map = GetWxOrderno.doTransfer2(mch_id, certFile, transfersURL, xml);
            if (null == map) {
                vo.setMessage("调起接口失败");
                return vo;
            }

            String paymentNo = null;
            Date paymentTime = null;

            //请见https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2
            String return_code = map.get("return_code");
            if (return_code.equals("SUCCESS")) {
                String result_code = map.get("result_code");
                if (result_code.equals("SUCCESS")) {
                    paymentNo = map.get("payment_no");
                    String payment_time = map.get("payment_time");

                    try {
                        paymentTime = DateUtils.parseDate(payment_time, "yyyy-MM-dd HH:mm:ss");
                    } catch (ParseException e) {

                        e.printStackTrace();
                    }

                } else {
                    String err_code = map.get("err_code");
                    String err_code_des = map.get("err_code_des");
                    vo.setMessage(err_code_des + "(" + err_code + ")");
                    return vo;
                }
            } else {
                String return_msg = map.get("return_msg");
                vo.setMessage(return_msg);
                return vo;
            }

            db_weixinManagerTixianRecord.setOperating(principal.getUsername());
            db_weixinManagerTixianRecord.setStatus(WeixinManagerTixianRecord.STATUS_OK);
            db_weixinManagerTixianRecord.setPaymentNo(paymentNo);
            db_weixinManagerTixianRecord.setPaymentTime(paymentTime);
            weixinManagerTixianRecordMapper.updateByPrimaryKey(db_weixinManagerTixianRecord);

            vo.setSuccess(true);
            return vo;

        } else if (weixinManagerTixianRecord.getStatus()
            .equals(WeixinManagerTixianRecord.STATUS_FAILED)) {
            if (null != weixinManager) {
                weixinManagerMapper
                    .updateVirtual(weixinManager.getId(), weixinManagerTixianRecord.getMoney());

                //财务记录
                WeixinManagerPayments weixinManagerPayments = new WeixinManagerPayments();
                weixinManagerPayments.setManagerId(weixinManager.getId());
                weixinManagerPayments.setMoney(weixinManagerTixianRecord.getMoney());
                weixinManagerPayments.setAfterVirtual(
                    weixinManager.getVirtual().add(weixinManagerTixianRecord.getMoney()));
                weixinManagerPayments
                    .setRecordType(WeixinManagerPayments.RECORD_TYPE_RECHARGE_TITIAN);
                weixinManagerPaymentsMapper.insertRecord(weixinManagerPayments);
            }

            db_weixinManagerTixianRecord.setOperating(principal.getUsername());
            db_weixinManagerTixianRecord.setStatus(WeixinManagerTixianRecord.STATUS_FAILED);
            weixinManagerTixianRecordMapper.updateByPrimaryKey(db_weixinManagerTixianRecord);

            vo.setSuccess(true);
            return vo;
        } else {
            vo.setMessage("无效的操作");
            return vo;
        }

    }

    @Transactional(rollbackFor = Exception.class)
    public void tixianApply(
        WeixinManagerTixianRecord weixinManagerTixianRecord,
        WeixinManager weixinManager) {

        //余额变更
        weixinManagerMapper
            .updateVirtual(weixinManager.getId(), weixinManagerTixianRecord.getMoney().negate());

        //提现记录
        weixinManagerTixianRecord.setManagerId(weixinManager.getId());
        weixinManagerTixianRecord.setManagerName(weixinManager.getName());
        weixinManagerTixianRecord.setManagerPhone(weixinManager.getPhone());
        weixinManagerTixianRecord.setManagerWxAccount(weixinManager.getWxAccount());
        weixinManagerTixianRecord.setCompanyId(weixinManager.getCompanyId());
        weixinManagerTixianRecord.setAfterMoney(
            weixinManager.getVirtual().subtract(weixinManagerTixianRecord.getMoney()));
        weixinManagerTixianRecord.setStatus(WeixinManagerTixianRecord.STATUS_NOTYET);
        weixinManagerTixianRecordMapper.insertRecord(weixinManagerTixianRecord);

        //财务记录
        WeixinManagerPayments weixinManagerPayments = new WeixinManagerPayments();
        weixinManagerPayments.setManagerId(weixinManager.getId());
        weixinManagerPayments.setMoney(weixinManagerTixianRecord.getMoney().negate());
        weixinManagerPayments.setAfterVirtual(
            weixinManager.getVirtual().subtract(weixinManagerTixianRecord.getMoney()));
        weixinManagerPayments.setRecordType(WeixinManagerPayments.RECORD_TYPE_CONSUMED_TITIAN);
        weixinManagerPaymentsMapper.insertRecord(weixinManagerPayments);

    }


    @Override
    public Long countNewByCompany(Long companyId) {

        Long tixianAmount = weixinManagerTixianRecordMapper.countNewByCompany(companyId);
        if (null == tixianAmount) {
            tixianAmount = 0L;
        }
        return tixianAmount;

    }

    @Override
    public Long countNewByManager(Long managerId) {

        Long tixianAmount = weixinManagerTixianRecordMapper.countNewByManager(managerId);
        if (null == tixianAmount) {
            tixianAmount = 0L;
        }
        return tixianAmount;
    }


}